using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;

namespace Jbe.TestSuite.TestDevice.SignalVisualizer.Views
{
    /// <summary>
    /// Interaction logic for SignalView.xaml
    /// </summary>
    public partial class SignalView : UserControl, INotifyPropertyChanged
    {
        private double scaleX = 1;
        private double scaleY = 1;
        private Dictionary<object, Polyline> polylines;
        
        /// <summary>
        /// The scaling of the x-axis.
        /// </summary>
        public double ScaleX
        {
            get { return scaleX; }
            set
            {
                if (scaleX != value)
                {
                    scaleX = value;
                    UpdateTransform();
                    OnPropertyChanged("ScaleX");
                }
            }
        }

        /// <summary>
        /// The scaling of the y-axis.
        /// </summary>
        public double ScaleY
        {
            get { return scaleY; }
            set
            {
                if (scaleY != value)
                {
                    scaleY = value;
                    UpdateTransform();
                    OnPropertyChanged("ScaleY");
                }
            }
        }
        
        public SignalView()
        {
            InitializeComponent();

            polylines = new Dictionary<object, Polyline>();
            
            ClipToBounds = true;
            SizeChanged += new SizeChangedEventHandler(ThisSizeChanged);
            
            DrawAxes();
        }

        public void AddSample(object device, double x, double y)
        {
            Polyline polyline;
            if (polylines.ContainsKey(device)) { polyline = polylines[device]; }
            else { polyline = AddPolyline(device); }
            
            polyline.Points.Add(new Point(x, y));
        }

        protected Polyline AddPolyline(object device)
        {
            Polyline polyline = new Polyline();
            polyline.Stroke = Brushes.Black;
            polyline.StrokeThickness = 1;

            polylines.Add(device, polyline);
            contentCanvas.Children.Add(polyline);
            return polyline;
        }

        private void ThisSizeChanged(object sender, SizeChangedEventArgs e)
        {
            UpdateTransform();
        }

        private void DrawAxes()
        {
            Line horizontalLine = new Line();
            horizontalLine.X1 = -3000;
            horizontalLine.Y1 = 0;
            horizontalLine.X2 = 3000;
            horizontalLine.Y2 = 0;
            horizontalLine.Stroke = System.Windows.Media.Brushes.Black;
            horizontalLine.StrokeThickness = 0.5;
            horizontalLine.IsHitTestVisible = false;

            mainCanvas.Children.Add(horizontalLine);
        }

        private void UpdateTransform()
        {
            mainCanvas.RenderTransform = new MatrixTransform(1, 0, 0, -1, 0, ActualHeight / 2);
            contentCanvas.RenderTransform = new ScaleTransform(ScaleX, ScaleY);
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); }
        }

        #endregion
    }
}